﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;

namespace ImageRecognition2.MouseImageTools
{
    /// <summary>
    /// Mouse Image toolbase
    /// </summary>
    public abstract class MouseImageToolBase : IDisposable
    {
        #region Declarations
        public abstract void OnMouseDown(object sender, MouseEventArgs e);
        public abstract void OnMouseUp(object sender, MouseEventArgs e);
        public abstract void OnMouseMove(object sender, MouseEventArgs e);
        private string m_sName = "";
        private bool m_bIsActive = false;
        private string m_sHelpText = "";

        private object m_oOwner = null;
        private object m_UserObject = null;
        protected Control m_Control = null;

        //private Form m_FormControl = null;

        public event EventHandler OnActivateEventHandler;
        public event EventHandler OnDeactivateEventHandler;
        #endregion Declarations

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="CTool"/> class.
        /// </summary>
        public MouseImageToolBase(Control _control)
        {
            m_Control = _control;
        }

        /// <summary>
        /// Gets or sets the control.
        /// </summary>
        /// <value>The control.</value>
        public Control Control
        {
            get { return m_Control; }
            set { m_Control = value; }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="CTool"/> class.
        /// </summary>
        /// <param name="_sName">Name of the _s.</param>
        public MouseImageToolBase(string _sName)
        {
            this.m_sName = _sName;
        }
        #endregion Constructors

        #region Properties
        /// <summary>
        /// Gets or sets the user object.
        /// </summary>
        /// <value>The user object.</value>
        public object UserObject
        {
            get { return m_UserObject; }
            set { m_UserObject = value; }
        }
      
        /// <summary>
        /// Gets or sets the owner.
        /// </summary>
        /// <value>The owner.</value>
        public object Owner
        {
            get { return this.m_oOwner; }
            set { this.m_oOwner = value; }
        }

        /// <summary>
        /// Gets or sets a value indicating whether this instance is active.
        /// </summary>
        /// <value><c>true</c> if this instance is active; otherwise, <c>false</c>.</value>
        public bool IsActive
        {
            get { return this.m_bIsActive; }
        }

        /// <summary>
        /// Gets or sets the help text.
        /// </summary>
        /// <value>The help text.</value>
        public string HelpText
        {
            get { return this.m_sHelpText; }
            set { this.m_sHelpText = value; }
        }

        /// <summary>
        /// Gets or sets the name.
        /// </summary>
        /// <value>The name.</value>
        public string Name
        {
            get { return this.m_sName; }
            set { this.m_sName = value; }
        }
        #endregion Properties

        #region Events
        /// <summary>
        /// Called when [paint].
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.Forms.PaintEventArgs"/> instance containing the event data.</param>
        public virtual void OnPaint(object sender, PaintEventArgs e)
        {
        }
        #endregion Events

        #region Methods
        /// <summary>
        /// Inits the name.
        /// </summary>
        protected void InitName()
        {
            this.m_sName = this.GetType().Name.Replace("Tool", " Tool");
        }

        /// <summary>
        /// Deactivates this instance.
        /// </summary>
        /// <returns></returns>
        public bool Deactivate()
        {
            SetEventHandlerState(false);
            this.m_bIsActive = false;
            if (this.OnDeactivateEventHandler != null)
            {
                this.OnDeactivateEventHandler(this, new EventArgs());
            }
            return !this.m_bIsActive;
        }

        /// <summary>
        /// Activates this instance.
        /// </summary>
        /// <returns></returns>
        public bool Activate()
        {
            SetEventHandlerState(true);
            if (this.OnDeactivateEventHandler != null)
            {
                this.OnDeactivateEventHandler(this, new EventArgs());
            }
            this.m_bIsActive = true;
            return this.m_bIsActive;
        }

        /// <summary>
        /// SetEventHandler
        /// </summary>
        /// <param name="_bSet"></param>
        private void SetEventHandlerState(bool _bSet)
        {
            if (_bSet)
            {
                m_Control.MouseDown += new MouseEventHandler(OnMouseDown);
                m_Control.MouseUp += new MouseEventHandler(OnMouseUp);
                m_Control.MouseMove += new MouseEventHandler(OnMouseMove);
            }
            else
            {
                m_Control.MouseDown -= new MouseEventHandler(OnMouseDown);
                m_Control.MouseUp -= new MouseEventHandler(OnMouseUp);
                m_Control.MouseMove -= new MouseEventHandler(OnMouseMove);
            }
        }

        /// <summary>
        /// Determines whether this instance can activate.
        /// </summary>
        /// <returns>
        /// 	<c>true</c> if this instance can activate; otherwise, <c>false</c>.
        /// </returns>
        public bool CanActivate()
        {
            return false;
        }


        /// <summary>
        /// Disposes this instance
        /// </summary>
        public virtual void Dispose()
        {
            throw new Exception("You have to override this method!");
        }

        /// <summary>
        /// Initializes this instance.
        /// </summary>
        public virtual void Initialize()
        {
            throw new Exception("You have to override this method!");
        }

        /// <summary>
        /// Draws the reversible rectangle.
        /// </summary>
        /// <param name="p1">The p1.</param>
        /// <param name="p2">The p2.</param>
        /// <param name="color">The color.</param>
        /// <param name="frameStyle">The frame style.</param>
        /// <returns></returns>
        protected Rectangle DrawReversibleRectangle(Point p1, Point p2, Color color, FrameStyle frameStyle)
        {
            Rectangle rectangle = new Rectangle();
            p1 = this.Control.PointToScreen(p1);
            p2 = this.Control.PointToScreen(p2);
            if (p1.X < p2.X)
            {
                rectangle.X = p1.X;
                rectangle.Width = p2.X - p1.X;
            }
            else
            {
                rectangle.X = p2.X;
                rectangle.Width = p1.X - p2.X;
            }
            if (p1.Y < p2.Y)
            {
                rectangle.Y = p1.Y;
                rectangle.Height = p2.Y - p1.Y;
            }
            else
            {
                rectangle.Y = p2.Y;
                rectangle.Height = p1.Y - p2.Y;
            }

            ControlPaint.DrawReversibleFrame(rectangle, color, frameStyle);
            return rectangle;
        }
        #endregion Methods
    }
}
